package com.dunshan.deeptest.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dunshan.deeptest.mapper.ScriptParamMapper;
import com.dunshan.deeptest.pojo.Result;
import com.dunshan.deeptest.pojo.ScriptParam;
import com.dunshan.deeptest.service.ScriptService;
import com.dunshan.deeptest.utils.HttpUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;

/**
 * @author .dunshan
 * @program: dunshan-pef
 * @description: 接口解析与执行
 * @date 2021-12-30 16:57:35
 */
@Log4j2
@Service
public class ScriptServiceImpl implements ScriptService {

    @Autowired
    ScriptParamMapper scriptParamMapper;

    /**
     * 解析url
     *
     * @param url
     * @return
     */
    @Override
    public Result printUrlInfo(String url) {
        JSONObject body = new JSONObject();
        JSONArray paramArray = new JSONArray();
        JSONArray headerArray = new JSONArray();
        int find = url.indexOf("?");
        if (find == -1) {
            return Result.buildFailed();
        }

        String para = url.substring(find + 1);
        String[] paramList = para.split("&");
        for (String paraKey : paramList) {
            String[] equal = paraKey.split("=");
            JSONObject parameter = new JSONObject();
            parameter.put("name", equal[0]);
            parameter.put("value", equal[1]);
            paramArray.add(parameter);
        }
        JSONObject header = new JSONObject();
        header.put("name", "");
        header.put("value", "");
        headerArray.add(header);
        String urlPath = url.substring(0, find);
        int hostPath = urlPath.lastIndexOf("/");
        body.put("host", url.substring(0, hostPath));
        body.put("path", url.substring(hostPath, find));
        body.put("header", headerArray);
        body.put("parameter", paramArray);
        return Result.buildSuccess(body);
    }

    /**
     * 执行
     *
     * @param scriptParam
     * @return
     */
    @Override
    public Result testRun(ScriptParam scriptParam) {
        if (StringUtils.isNotBlank(scriptParam.getDiffCaseName())) {
            //表示需要对比
            JSONObject map = new JSONObject();
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.ge("script_name", scriptParam.getDiffCaseName());
            ScriptParam ScriptName = scriptParamMapper.selectOne(queryWrapper);
            map.put("one", execute(scriptParam).getData());
            //需要根据接口名字查询参数
            map.put("two", execute(ScriptName).getData());
            return Result.buildSuccess(map);
        } else {
            //不需要对比
            return execute(scriptParam);
        }
    }

    @Override
    @Transactional
    public Result save(ScriptParam scriptParam) {
        if (scriptParam != null && StringUtils.isNotEmpty(scriptParam.getScriptName())
                && StringUtils.isNotEmpty(scriptParam.getPath())
                && StringUtils.isNotEmpty(scriptParam.getHost())) {
            scriptParam.setCreateTime(LocalDateTime.now());
            scriptParam.setParameter(JSONObject.toJSONString(scriptParam.getParameter()));
            scriptParam.setHeader(JSONObject.toJSONString(scriptParam.getHeader()));
            return Result.buildSuccess(scriptParamMapper.insert(scriptParam));
        }
        return Result.buildFailed();
    }

    @Override
    public Result update(ScriptParam scriptParam) {
        return Result.buildSuccess(scriptParamMapper.updateById(scriptParam));
    }

    @Override
    public Result delete(Integer id) {
        return Result.buildSuccess(scriptParamMapper.deleteById(id));
    }


    /**
     * 执行接口
     *
     * @param scriptParam 脚本参数
     * @return
     */
    private Result execute(ScriptParam scriptParam) {
        HashMap<String, String> query = new HashMap<>();
        HashMap<String, String> header = new HashMap<>();
        log.info("请求数{}", JSONObject.toJSON(scriptParam));

        JSONArray param = JSONArray.parseArray(scriptParam.getParameter().toString());
        paramHeaderInfo(query, param);
        JSONArray headers = JSONArray.parseArray(scriptParam.getHeader().toString());
        paramHeaderInfo(header, headers);
        try {
            HttpResponse httpResponse = null;
            if (scriptParam.getMethod().equalsIgnoreCase("get")) {
                httpResponse = HttpUtils.doGet(scriptParam.getHost(), scriptParam.getPath(), scriptParam.getMethod(), header, query);
            } else if (scriptParam.getMethod().equalsIgnoreCase("post")) {
                httpResponse = HttpUtils.doPost(scriptParam.getHost(), scriptParam.getPath(), scriptParam.getMethod(), header, query, scriptParam.getBody());
            }

            if (httpResponse != null && httpResponse.getStatusLine().getStatusCode() == 200) {
                String json = EntityUtils.toString(httpResponse.getEntity());
                return Result.buildSuccess(json);
            }
            return Result.buildFailed("100", "响应结果失败");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.buildFailed();
    }

    /**
     * 解析参数
     *
     * @param header  结果存放
     * @param headers 遍历参数
     */
    private void paramHeaderInfo(HashMap<String, String> header, JSONArray headers) {
        for (int i = 0; i < headers.size(); i++) {
            JSONObject params = JSONObject.parseObject(headers.get(i).toString());
            String name = params.getString("name");
            String value = params.getString("value");
            header.put(name, value);
        }
    }

}
